package com.xuerhua.yxt.websocket;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xuerhua.yxt.common.enums.FileType;
import com.xuerhua.yxt.utils.JsonUtils;
import com.xuerhua.yxt.websocket.model.Message;
import com.xuerhua.yxt.websocket.model.User;

@ServerEndpoint("/websocket/privateLetter") 
public class PrivateLetterWebSocket {

	private Logger logger = LoggerFactory.getLogger(ClassGroupChatWebSocket.class);
	
	//用来记录有多少个用户使用该websocket通道 
    private static Map<String, List<Session>> userListMap = new HashMap<>();
    /** 
     * 连接建立成功调用的方法 
     * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据 
     */  
    @OnOpen  
    public void onOpen(Session session){  
    	 String str = session.getQueryString();//可以得到ws：//路径？后面的所有字符串  
    	 User user = getUser(str);
         String clazzKey = getClazzKey(user.getGrade(), user.getClazz(), user.getStudentId());
         List<Session> list = userListMap.get(clazzKey);
         if(list == null) {
        	 list = new ArrayList<>();
        	 list.add(session);
        	 userListMap.put(clazzKey, list);
         }else {
			list.add(session);
		}
         Message message = new Message();
         message.setMessageType(FileType.TEXT.getCode());
         message.setMessage("欢迎 " + user.getUserName() + " 加入家长私信聊天");
         logger.info("----websocket onOpen, params={}, 当前人数={}", session.getQueryString(), list.size());
         sendMessage(list, message, session);
    } 
    
    /** 
     * 连接关闭调用的方法 
     */  
    @OnClose  
    public void onClose(Session session){  
    	User user = getUser(session.getQueryString());
        String clazzKey = getClazzKey(user.getGrade(), user.getClazz(), user.getStudentId());
        List<Session> list = userListMap.get(clazzKey);
        list.remove(session);
        Message message = new Message();
        message.setMessage(user.getUserName() + " 离开了家长私信聊天");
        logger.info("----websocket onOpen, onClose={}, 当前人数={}", session.getQueryString(), list.size());
        sendMessage(list, message, session);
    }  
    
    /** 
     * 收到客户端消息后调用的方法 
     * @param message 客户端发送过来的消息 
     * @param session 可选的参数 
     * @throws IOException 
     * @throws JsonMappingException 
     * @throws JsonParseException 
     */  
    @OnMessage  
    public void onMessage(String msg, Session session) throws JsonParseException, JsonMappingException, IOException {
    	Message message = JsonUtils.jsonToObject(msg, Message.class);
    	User user = getUser(session.getQueryString());
    	message.setUser(user);
    	String clazzKey = getClazzKey(user.getGrade(), user.getClazz(), user.getStudentId());
    	List<Session> list = userListMap.get(clazzKey);
    	sendMessage(list, message, session);
    }  
    
    public void sendMessage(List<Session> list, Message message, Session session) {
    	//群发消息  
        for(Session userSession : list){  
            try {
            	if(session.getId().equals(userSession.getId())) {
            		continue;
            	}
            	userSession.getBasicRemote().sendText(message.toJson());
            } catch (IOException e) {  
            	logger.error("----websocket sendMessage, params={}, error={}", userSession.getQueryString(), e);
                continue;  
            }  
        } 
    }
    
    /** 
     * 发生错误时调用 
     * @param session 
     * @param error 
     */  
    @OnError  
    public void onError(Session session, Throwable error){  
    	String str = session.getQueryString();
        logger.error("----websocket onError, params={}, error={}", str, error);
    }
    
    private static User getUser(String queryString) {
    	if (queryString != null && queryString.trim().length() > 0) {  
            try {
            	queryString = URLDecoder.decode(queryString, "UTF-8");  
            	Map<String, Object> map = new HashMap<>();
                String[] params = queryString.split("&");  
                for (int i = 0; i < params.length; i++) {  
                    int splitIndex = params[i].indexOf("=");  
                    if (splitIndex == -1) {  
                        continue;  
                    }  
                    String key = params[i].substring(0, splitIndex);  
                    String value = params[i].substring(splitIndex + 1);
                    map.put(key, value);
                } 
				return JsonUtils.mapToObject(map, User.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
    	}
    	return null;
    }
    
    private static String getClazzKey(int grade, int clazz, int studentId) {
    	return grade + "-" + clazz + "-" + studentId;
    }
    
}
